package com.xbongbong.paas.script.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.script.pojo.dto.FixRedContractCostDTO;
import com.xbongbong.pro.script.pojo.dto.FixRefundDTO;
import com.xbongbong.pro.script.pojo.dto.RefundContractProductDTO;
import com.xbongbong.pro.script.pojo.dto.RefundExplainFixDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.RefundEntityExt;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.model.*;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.SaasDetailTabService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.support.WriteRequest;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;

@Slf4j
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/refund")
public class RefundScriptController {
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    ContractModel contractModel;
    @Resource
    RefundModel refundModel;
    @Resource
    SaasDetailTabService saasDetailTabService;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    ContractProductModel contractProductModel;
    @Resource
    OutstockProductModel outstockProductModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private CustomerModel customerModel;

    /*
     * description:   修复合同关联产品  退货退款单的 退货数量    （原bug有脏数据 需要重新计算一下）(废弃)
     * date: 2021/6/4 2:43 下午
     * @return
     */
    @RequestMapping(value = "/fix/contractLinkedNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fix(@RequestBody @Valid FixRefundDTO fixRefundDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixRefundDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            String res = fix(fixRefundDTO);
            response = new XbbResponse<>(res);
        }
        return JSON.toJSONString(response);
    }

    public String fix(FixRefundDTO fixRefundDTO) throws XbbException {
        Map<Long, Double> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        StringBuffer res = new StringBuffer();
        String corpid = fixRefundDTO.getCorpid();
        List<Long> idIn = fixRefundDTO.getIdIn();

        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("del", BasicConstant.ZERO);
        params.put("idIn", idIn);
        List<ContractEntityExt> entitys = contractModel.findEntitys(params);

        for (ContractEntityExt contractEntityExt : entitys) {
            String serialNo = contractEntityExt.getSerialNo();

            Long id = contractEntityExt.getId();   // 合同id


            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(RedundantTemplateTypeEnum.REFUND.getCode(), corpid);
            String explains = paasFormExplainEntity.getExplains();
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);

            List<ConditionsEntityExt> conditions = new ArrayList<>();
            FormDataListDTO formDataListDTO = new FormDataListDTO();
            formDataListDTO.setAppId(null);
            formDataListDTO.setFormId(null);
            ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
            conditionsEntityExt.setAttr("text_2");
            conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
            conditionsEntityExt.setValue(Collections.singletonList(id));  // 2130
            conditionsEntityExt.setFieldType(FieldTypeEnum.TEXT.getType());
            conditions.add(conditionsEntityExt);
            formDataListDTO.setDel(DelEnum.NORMAL.getDel());
            formDataListDTO.setConditions(conditions);
            formDataListDTO.setBusinessType(RedundantTemplateTypeEnum.REFUND.getCode());
            formDataListDTO.setSortMap(null);
            formDataListDTO.setExplainMap(explainMap);
            formDataListDTO.setSearchSubForm(false);
            PaasFormDataEsListVO paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, IndexTypeEnum.IDX_SAAS_REFUND);
            List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();

            //  计算真正的此合同的产品退货数目

            for (PaasFormDataEntityExt entityExt : paasFormDataESList) {
                JSONObject data = entityExt.getData();
                long text_8 = data.getLong("text_8");

                ContractEntityExt redContract = contractModel.getByKey(text_8, corpid);
                Long redContractId = redContract.getId();

                params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("corpid", corpid);
                params.put("del", BasicConstant.ZERO);
                params.put("contractId", redContractId);
                List<ContractProductEntity> redContractProducts = contractProductModel.findEntitys(params);

                for (ContractProductEntity entity : redContractProducts) {
                    Double num = entity.getProductNum();
                    Long productId = entity.getProductId();
                    if (map.containsKey(productId)) {
                        Double aDouble = map.get(productId);
                        map.put(productId, Arith.add(aDouble, num));
                    } else {
                        map.put(productId, num);
                    }
                }
            }


            //更新 合同关联产品的
            params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("del", BasicConstant.ZERO);
            params.put("contractId", id);
            List<ContractProductEntity> contractProducts = contractProductModel.findEntitys(params);

            for (ContractProductEntity entity : contractProducts) {
                Long productId = entity.getProductId();
                Double instockNum = entity.getInstockNum();
                Double temp = map.get(productId);
                if (!Objects.nonNull(temp)) {
                    continue;
                }
                Double realInstockNum = Math.abs(map.get(productId));       // 真正的
                if (instockNum != realInstockNum) {
                    List<ContractProductEntity> list = new ArrayList<>();
                    list.add(entity);
                    entity.setInstockNum(realInstockNum - instockNum);    // 复用此更新sql   此sql的instockNum  是在原有基础上叠加的   重新设值需要减掉之前的
                    contractProductModel.updateInStock(list, corpid);
                }
            }

            params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("del", BasicConstant.ZERO);
            params.put("refId", id);
            List<OutstockProductEntity> outstockProductModelEntitys = outstockProductModel.findEntitys(params);

            for (OutstockProductEntity entity : outstockProductModelEntitys) {
                Long productId = entity.getProductId();
                Double instockNum = entity.getInstockNum();
                Double temp = map.get(productId);
                if (!Objects.nonNull(temp)) {
                    continue;
                }
                Double realInstockNum = Math.abs(map.get(productId));       // 真正的
                if (instockNum != realInstockNum) {
                    List<ContractProductEntity> list = new ArrayList<>();
                    entity.setInstockNum(realInstockNum);
                    outstockProductModel.update(entity);
                }
            }
//            Map<Long,Double> map

            for (Map.Entry<Long, Double> entrySet : map.entrySet()) {
                Long key = entrySet.getKey();
                Double value = entrySet.getValue();
                res.append(key + ":" + value + ";");
            }
        }
        return res.toString();
    }


    @RequestMapping(value = "/fix/redContractCost", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String redContractCost(@RequestBody @Valid FixRedContractCostDTO fixRedContractCostDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixRedContractCostDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            String res = fixRedContractCost(fixRedContractCostDTO);
            response = new XbbResponse<>(res);
        }
        return JSON.toJSONString(response);
    }

    String fixRedContractCost(FixRedContractCostDTO fixRedContractCostDTO) throws XbbException {
        int fixNum = 0;
        String corpid = fixRedContractCostDTO.getCorpid();
        List<String> serialNoIn = fixRedContractCostDTO.getSerialNoIn();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("serialNoIn", serialNoIn);
        param.put("del", 0);
        List<ContractEntityExt> redContractEntities = contractModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(redContractEntities)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "红冲合同未找到");
        }
        List<Long> contractIdIn = new ArrayList<>();
        Map<Long, ContractEntityExt> redContractIdAndContractEntityExtMap = new HashMap<>();
        for (ContractEntityExt temp : redContractEntities) {
            Long id = temp.getId();
            contractIdIn.add(id);
            redContractIdAndContractEntityExtMap.put(id, temp);
        }
        param.clear();
        param.put("corpid", corpid);
        param.put("contractIdIn", contractIdIn);
        param.put("del", 0);
        List<ContractProductEntity> contractProductEntities = contractProductModel.findEntitys(param);
        Map<Long, List<ContractProductEntity>> groupBy = contractProductEntities.stream().
                collect(Collectors.groupingBy(ContractProductEntity::getContractId));
        Set<Long> contractIdSet = groupBy.keySet();
        for (Long temp : contractIdSet) {
            List<ContractProductEntity> productEntities = groupBy.get(temp);
            Double redContractCost = 0D;
            Map<Long, Double> productIdAndNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, Double> webProductIdAndNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, Double> batchProductIdAndNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (int i = 0; i < productEntities.size(); i++) {
                ContractProductEntity entity = productEntities.get(i);
                JSONObject jsonObject = entity.getData();
                Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
                Double productNum = jsonObject.getDouble(ContractProductEnum.NUM.getAttr());
                String batchNum = jsonObject.getString(RefundProductEnum.BATCH.getAttr());
                String key = pageProductId.toString();
                if (StringUtils.isNotEmpty(batchNum)) {
                    key = key + batchNum;
                }
                if (batchProductIdAndNumMap.containsKey(key)) {
                    productNum = Arith.add(batchProductIdAndNumMap.get(key), productNum);
                }
                batchProductIdAndNumMap.put(key, productNum);
                // 退货产品ID以及对应的数量
                if (productIdAndNumMap.containsKey(pageProductId)) {
                    productNum = Arith.add(productIdAndNumMap.get(pageProductId), productNum);
                }
                productIdAndNumMap.put(pageProductId, -productNum);
                webProductIdAndNumMap.put(pageProductId, productNum);
            }
            // 序列号
            param.clear();
            param.put("corpid", corpid);
            param.put("serialNo", redContractIdAndContractEntityExtMap.get(temp).getSerialNo());
            param.put("del", 0);
            List<RefundEntityExt> entitys = refundModel.findEntitys(param);
            RefundEntityExt refundEntityExt = entitys.get(0);
            Long contractId = FastJsonHelper.getLongOrDefaultFromFormData(refundEntityExt.getData(), RefundEnum.CONTRACT_ID.getAttr(), 0L);
            ContractEntityExt contractEntityExt = contractModel.getByKey(contractId, corpid);
            List<Long> outstockIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(contractEntityExt.getData(), ContractEnum.OUTSTOCK_ID.getAttr(), new JSONArray()).toJavaList(Long.class);
            if (!outstockIdList.isEmpty()) {
                Map<String, Object> outstockParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                outstockParam.put("corpid", corpid);
                outstockParam.put("del", DelEnum.NORMAL.getDel());
                outstockParam.put("outstockIdIn", outstockIdList);
                List<OutstockProductEntity> outstockProductList = outstockProductModel.findEntitys(outstockParam);
                Map<Long, OutstockProductEntity> outstockProductEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                // 算出每个产品对应的成本
                Map<String, Double> batchProductIdAndCostMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                // 所有的出库记录
                for (OutstockProductEntity outstockProductEntity : outstockProductList) {
                    Long productId = outstockProductEntity.getProductId();
                    Double productNum = outstockProductEntity.getProductNum() == null ? 0D : outstockProductEntity.getProductNum();
                    Double productCost = outstockProductEntity.getCost() == null ? 0D : outstockProductEntity.getCost();
                    String batchNum = outstockProductEntity.getBatch();
                    String key = productId.toString();
                    if (StringUtils.isNotEmpty(batchNum)) {
                        key = key + batchNum;
//                            batchProductIdAndNumMap.put(key, productNum);
                    }
                    batchProductIdAndCostMap.put(key, productCost);
                }
                // 遍历红冲合同
                Iterator iterator = batchProductIdAndNumMap.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next().toString();
                    Double productNum = batchProductIdAndNumMap.get(key);
                    if (batchProductIdAndCostMap.containsKey(key)) {
                        // 取负
                        redContractCost = Arith.add(redContractCost, Arith.mul(productNum, -batchProductIdAndCostMap.get(key)));
                    }
                }
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "出库单未找到");
            }
            ContractEntityExt redContractEntity = redContractIdAndContractEntityExtMap.get(temp);
            JSONObject redContractData = redContractEntity.getData();
            Double returnAmount = getDoubleOrDefaultFromFormData(refundEntityExt.getData(), RefundEnum.RETURN_AMOUNT.getAttr(), 0D);
            // 更新红冲合同的合同成本，合同毛利，现金毛利
            redContractData.put(ContractEnum.CONTRACT_COST.getAttr(), redContractCost);
            redContractData.put(ContractEnum.GROSS_PROFIT.getAttr(), Arith.sub(-returnAmount, redContractCost));
            Double refundAmount = getDoubleOrDefaultFromFormData(refundEntityExt.getData(), RefundEnum.REFUND_AMOUNT.getAttr(), 0D);
            redContractData.put(ContractEnum.CASH_PROFIT.getAttr(), Arith.sub(-refundAmount, redContractCost));
            redContractEntity.setData(redContractData);
            contractModel.update(redContractEntity);
            fixNum++;
        }
        return "success: " + fixNum;
    }


    @RequestMapping(value = "/fix/refundContractProductNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String refundContractProductNum(@RequestBody @Valid RefundContractProductDTO productDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(productDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            String res = refundContractProductNum(productDTO);
            response = new XbbResponse<>(res);
        }
        return JSON.toJSONString(response);
    }

    private String refundContractProductNum(RefundContractProductDTO productDTO) throws XbbException {
        String corpid = productDTO.getCorpid();
        Long refundId = productDTO.getRefundId();
        // 查询需要修复的退货退款单
        Map<String, Object> refundParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        refundParam.put("corpid", corpid);
        refundParam.put("id", refundId);
        refundParam.put("del", 0);
        List<RefundEntityExt> refundEntityExtList = refundModel.findEntitys(refundParam);
        if (CollectionsUtil.isEmpty(refundEntityExtList)) {
            return "未找到对应的退货退款单";
        }
        // 获取退货入库单ID
        RefundEntityExt refundEntityExt = refundEntityExtList.get(0);
        JSONObject refundData = refundEntityExt.getData();
        JSONArray instockIdArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(refundData, RefundEnum.INSTOCK_ID.getAttr(), new JSONArray());
        if (CollectionsUtil.isEmpty(instockIdArr)) {
            return "未找到对应的退货入库单";
        }
        List<Long> instocks = instockIdArr.toJavaList(Long.class);
        List<InstockProductEntity> instockProductsList = instockProductModel.getProductsByInstockIdIn(corpid, instocks);
        if (CollectionsUtil.isEmpty(instockProductsList)) {
            return "未找到对应的退货入库单产品";
        }
        // 获取退货退款关联的合同订单
        String contractId = FastJsonHelper.getStringFromFormData(refundData, RefundEnum.CONTRACT_ID.getAttr());
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("contractId", contractId);
        param.put("type", XbbRefTypeEnum.REFUND.getCode());
        param.put("del", 0);
        // 拿到合同的所有产品
        List<ContractProductEntity> contractProductEntityList = contractProductModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(contractProductEntityList)) {
            return "未找到对应的合同订单";
        }
        Map<Long, Double> refundNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ContractProductEntity> updateList = new ArrayList<>();
        instockProductsList.forEach(item -> {
            if (Objects.nonNull(item.getRefProductId())) {
                Double num = refundNumMap.getOrDefault(item.getRefProductId(), 0D);
                num = Arith.add(num, item.getProductNum());
                refundNumMap.put(item.getRefProductId(), num);
            }
        });
        for (ContractProductEntity entity : contractProductEntityList) {
            Long key = entity.getId();
            if (refundNumMap.containsKey(key)) {
                // 当前入库
                Double amendNum = refundNumMap.get(key);
                entity.setInstockNum(amendNum);
                entity.setUpdateTime(DateTimeUtil.getInt());
                updateList.add(entity);
            }
        }
        if (!updateList.isEmpty()) {
            contractProductModel.updateInStock(updateList, corpid);
        }
        return "success";
    }

    /**
     * bugid 54743 【成功部】手机端工单关联客户乱码
     * date: 2023/1/3 08:49
     *
     * @param :
     * @author yingjf
     */
    @RequestMapping(value = "/fix/explain", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    private String fixRefundExplain(@RequestBody @Valid RefundExplainFixDTO refundExplainFixDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(refundExplainFixDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            // 修复解释
            fixRefundExplain(refundExplainFixDTO);
            // 修复数据
            fixRefundData(refundExplainFixDTO);
            response = new XbbResponse<>("success");
        }
        return JSON.toJSONString(response);
    }

    /**
     * bugid 54743 【成功部】手机端工单关联客户乱码
     * date: 2023/1/3 08:52
     *
     * @param :
     * @author yingjf
     */
    private void fixRefundExplain(RefundExplainFixDTO refundExplainFixDTO) throws XbbException {
        String corpid = refundExplainFixDTO.getCorpid();
        PaasFormExplainEntity formExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.REFUND.getCode(), corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(formExplainEntity.getExplains());
        FieldAttrEntity fieldAttrEntity = explainMap.get(RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr());
        fieldAttrEntity.setAttr("text_29");
        explainMap.put("text_29", fieldAttrEntity);
        // 原始的text_9字段解释
        FieldAttrEntity customerIdLinkedText = InitExplainsHelper.getNewFieldAttrEntity();
        customerIdLinkedText.setAttrType("text");
        BeanUtil.copyProperties(RefundEnum.CUSTOMER_ID_LINKED_TEXT, customerIdLinkedText);
        explainMap.put(RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr(), customerIdLinkedText);

        List<FieldAttrEntity> list = new ArrayList<>();
        explainMap.forEach((key, value) -> {
            list.add(value);
        });
        formExplainEntity.setExplains(JSON.toJSONString(list));
        paasFormExplainModel.update(formExplainEntity);
    }

    /**
     * 修复数据
     * date: 2023/1/3 10:25
     *
     * @param refundExplainFixDTO:
     * @author yingjf
     */
    private void fixRefundData(RefundExplainFixDTO refundExplainFixDTO) throws XbbException {
        // 470条数据
        String corpid = refundExplainFixDTO.getCorpid();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("del", DelEnum.NORMAL.getDel());
        List<RefundEntityExt> entitys = refundModel.findEntitys(params);
        List<Long> customerIdList = new ArrayList<>();
        entitys.forEach(item -> {
                    JSONObject data = item.getData();
                    Long customerId = data.getLong(RefundEnum.CUSTOMER_ID.getAttr());
                    customerIdList.add(customerId);
                }
        );
        params.clear();
        List<CustomerEntityExt> customerEntityExtList = customerModel.getByKeys(customerIdList, corpid);
        Map<Long, String> customerIdAndNameMap = new HashMap<>();
        customerEntityExtList.forEach(item -> {
            JSONObject data = item.getData();
            Long id = item.getId();
            String name = data.getString(CustomerManagementEnum.NAME.getAttr());
            customerIdAndNameMap.put(id, name);
        });
        List<UpdateDataEntity> list = new ArrayList<>();
        entitys.forEach(item -> {
            JSONObject data = item.getData();
            Long id = item.getId();
            Object customerIdLinkedText = data.get(RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr());
            Long customerId = data.getLong(RefundEnum.CUSTOMER_ID.getAttr());
            String customerName = customerIdAndNameMap.get(customerId);
            JSONObject temp = new JSONObject();
            if (customerIdLinkedText != null) {
                temp.put("text_29", customerIdLinkedText);
            }
            temp.put(RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr(), customerName);
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(id, temp, corpid);
            list.add(updateData);
        });
        if (CollectionsUtil.isNotEmpty(list)) {
            refundModel.updateBatch(list, corpid);
        }
    }


    /**
     * 58313 【紧急】【KA大客户】【B级】退货退款单列表不显示关联客户    如果退货退款数据量大  需要改造成分页
     * curl http://127.0.0.1:2019/pro/v1/script/refund/sync/customer -X POST -H 'Content-type: application/json' -d '{"corpid":"xbbxing","userId":"1","saasMark":1,"platform":"web","frontDev":"1","xbbCode":"123456"}'
     * date: 2023/1/3 08:49
     *
     * @param :
     * @author yingjf
     */
    @RequestMapping(value = "/sync/customer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    private String syncCustomer(@RequestBody @Valid RefundExplainFixDTO refundExplainFixDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(refundExplainFixDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            // 修复
            log.info("开始修复=====");
            syncCustomer(refundExplainFixDTO);
            response = new XbbResponse<>("success");
            log.info("结束修复=====");
        }
        return JSON.toJSONString(response);
    }

    /**
     * 同步客户名
     * date: 2023/1/16 09:26
     *
     * @param :
     * @author yingjf
     */
    private void syncCustomer(RefundExplainFixDTO refundExplainFixDTO) throws XbbException {
        String corpid = refundExplainFixDTO.getCorpid();
        if(StringUtils.isEmpty(corpid)){
            log.info("corpid不可为空");
            return;
        }
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("del", DelEnum.NORMAL.getDel());
        List<RefundEntityExt> refundEntityExtList = refundModel.findEntitys(params);
        if (CollectionsUtil.isEmpty(refundEntityExtList)) {
            return;
        }
        if(refundEntityExtList.size()>2000){
            log.info("退货退款数据量大不作处理");
        }
        log.info("需修复{}条数据", refundEntityExtList.size());
        List<Long> customerIdList = new ArrayList<>();
        for (RefundEntityExt temp : refundEntityExtList) {
            Long id = temp.getId();
            JSONObject data = temp.getData();
            Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data, RefundEnum.CUSTOMER_ID.getAttr(), 0L);
            customerIdList.add(customerId);
        }
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("ids", customerIdList);
//        param.put("del", BasicConstant.ZERO);
        List<CustomerEntityExt> customerEntityExtList = customerModel.findEntitys(param);
        Map<Long, String> customerIdAndNameMap = new HashMap<>();
        customerEntityExtList.forEach(item -> {
            JSONObject data = item.getData();
            Long id = item.getId();
            String name = data.getString(CustomerManagementEnum.NAME.getAttr());
            customerIdAndNameMap.put(id, name);
        });
        List<UpdateDataEntity> list = new ArrayList<>();
        for (RefundEntityExt item : refundEntityExtList) {
            Long id = item.getId();
            JSONObject data = item.getData();
            Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data, RefundEnum.CUSTOMER_ID.getAttr(), 0L);
            String customerName = customerIdAndNameMap.get(customerId);
            JSONObject temp = new JSONObject();
            temp.put(RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr(), customerName);
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(id, temp, corpid);
            list.add(updateData);
        }
        if (CollectionsUtil.isNotEmpty(list)) {
            refundModel.updateBatch(list, corpid);
        }

    }

}
